﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using KZ400B;
using System.ComponentModel;
using System.Windows.Threading;
using System.Windows.Controls.Primitives;
using KZ400B.Data;

namespace KZ400BApp
{
    /// <summary>
    /// TPlan.xaml 的交互逻辑
    /// </summary>
    public partial class TPlan : Window
    {
        TPlanManager m_tManager = new TPlanManager();
        
        
        List<DB.Model.TPlanAxle> m_axleList = new List<DB.Model.TPlanAxle>();

        //private GroupStyle _defaultGroupStyle;
        //private IEditableCollectionView iecv;

        private ControlTemplate _newRowControlTemplate;
        private ControlTemplate _defaultRowControlTemplate;
        public TPlan()
        {
            InitializeComponent();

#if DEBUG
            tbState.Visibility = System.Windows.Visibility.Visible;
#else
            tbState.Visibility = System.Windows.Visibility.Collapsed;
#endif

            //_defaultGroupStyle = (GroupStyle)gridStep.FindResource("gs_Default");
            //if (_defaultGroupStyle == null)
            //{
            //    throw new NullReferenceException("Unable to find gs_Default from the resources.");
            //}

            _newRowControlTemplate = (ControlTemplate)gridStep.FindResource("NewRow_ControlTemplate");
            if (_newRowControlTemplate == null)
            {
                throw new NullReferenceException("Unable to find NewRow_ControlTemplate from the resources.");
            }

            // update config bindings
            //ICollectionView view = CollectionViewSource.GetDefaultView(gridStep.ItemsSource);
            //iecv = (IEditableCollectionView)view;
            //this.NewItemPlaceholderPositionCB.DataContext = iecv;

            Loaded += new RoutedEventHandler(TPlan_Loaded);
            Unloaded += new RoutedEventHandler(TPlan_Unloaded);
            //AxleManager.OnAxleActionResponse += new AxleActionResponse(AxleManager_OnAxleActionResponse);
            spStatus.DataContext = m_tManager;
            tbState.DataContext = AxleStateBarMsg.Instance;
        }
        void invokeStateChange(string state)
        {
            //if (tbState != null && !string.IsNullOrEmpty(state))
            //{
            //    tbState.Dispatcher.Invoke(new Action(delegate()
            //    {
            //        tbState.Text = state;
            //    }
            //    ));
            //}
        }
        void AxleManager_OnAxleActionResponse(string axleName, Axle axle, AxleActions action, bool success, string message)
        {
            invokeStateChange(message); 
        }

        void TPlan_Unloaded(object sender, RoutedEventArgs e)
        {
            //m_tManager.OnStepChange -= new PlanStepChange(m_tManager_OnStepChange);
            //AxleManager.OnAxleActionResponse -= new AxleActionResponse(AxleManager_OnAxleActionResponse);
        }

        void TPlan_Loaded(object sender, RoutedEventArgs e)
        {
            List<DB.Model.TPlan> planList = m_tManager.getList();
            if (planList != null)
            {
                foreach (DB.Model.TPlan tp in planList)
                {
                    TPRStateManager.Instance.Update(tp.ID);
                }
            }

            bindPlans(0);
            //m_tManager.OnStepChange += new PlanStepChange(m_tManager_OnStepChange);
            spAxlePs.DataContext = PositionCacheManager.AxleStates;
            m_tManager.OnPlanCompleted += new PlanComplete(m_tManager_OnPlanCompleted);
        }

        void m_tManager_OnPlanCompleted(bool success)
        {
            MessageBox.Show(string.Format("方案运行[{0}]完成。", success ? "正确" : "失败"));
        }

        //int m_totalLoop = 0;
        //int m_step = 0;
        //int m_stepLoop = 0;
        //void m_tManager_OnStepChange(int totalLoop, int step, int stepLoop)
        //{
        //    //if (m_totalLoop != totalLoop)
        //    //{
        //    //    m_totalLoop = totalLoop;
        //    //    labTotalLoopDisplay.Dispatcher.BeginInvoke(new Action(delegate()
        //    //    {
        //    //        labTotalLoopDisplay.Text = totalLoop.ToString();
        //    //    })
        //    //        );
        //    //}
        //    //if (m_step != step)
        //    //{
        //    //    m_step = step;
        //    //    labStepDisplay.Dispatcher.BeginInvoke(new Action(delegate()
        //    //    {
        //    //        labStepDisplay.Text = step.ToString();
        //    //    })
        //    //        );
        //    //}
        //    //if (m_stepLoop != stepLoop)
        //    //{
        //    //    m_stepLoop = stepLoop;
        //    //    labStepLoopDisplay.Dispatcher.BeginInvoke(new Action(delegate()
        //    //    {
        //    //        labStepLoopDisplay.Text = stepLoop.ToString();
        //    //    })
        //    //        );
        //    //}
        //}

        private void btnRun_Click(object sender, RoutedEventArgs e)
        {
            if (!AxleManager.IsOpen)
            {
                KZ400B.Controls.StateMsgManager.addOneState("未连接,请检查连接状态!");
                return;
            }
             //m_totalLoop = 0;
             //m_step = 0;
             //m_stepLoop = 0;
            m_tManager.Run(getCurrentTPID());
        }

        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            if (!AxleManager.IsOpen)
            {
                KZ400B.Controls.StateMsgManager.addOneState("未连接,请检查连接状态!");
                return;
            }
            m_tManager.Stop(getCurrentTPID());
        }
        void bindPlans(int tplanId)
        {
            bindPlans(tplanId, true);
        }
        void bindPlans(int tplanId, bool rebindList)
        {
            bindPlans(tplanId, rebindList, false);
        }
        void bindPlans(int tplanId,bool rebindList,bool isCmbPlanSelectChange)
        {
            int tpid = getCurrentTPID();
            if (rebindList && !isCmbPlanSelectChange)
            {
                setTPlanID();
                bindAxleList();
                bindSteps();

                List<DB.Model.TPlan> planList = m_tManager.getList();
                //cmbPlan.Items.Clear();

                if (planList == null)
                {
                    planList = new List<DB.Model.TPlan>();
                }
                if (planList != null)
                {
                    planList.Insert(0, new DB.Model.TPlan() { ID = 0, Name = "请选择", LoopTimes = 0 });

                    cmbPlan.ItemsSource = planList;
                    cmbPlan.DisplayMemberPath = "Name";
                    cmbPlan.SelectedValuePath = "ID";
                }


                cmbPlan.SelectedValue = tplanId;
                    
                
            }

            //try
            //{

                //if (!rebindList)
                {
                    setTPlanID();
                    bindAxleList();
                    bindSteps();
                }
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show(ex.Message);
            //}
        }
        private void bindSteps()
        {
            int tpid = getCurrentTPID();

            if (tpid > 0)
            {
                DB.Model.TPlan tplan = m_tManager.getModel(tpid);
                if (tplan != null && tplan.StepList != null)
                {
                    List<DB.Model.TPlanStep> stepList = tplan.StepList;
                    
                    gridStep.ItemsSource = stepList;
                    ((DataGridComboBoxColumn)gridStep.Columns[0]).ItemsSource = m_axleList;
                    //((DataGridComboBoxColumn)gridStep.Columns[0]).DisplayMemberPath = "AxleName";
                    //((DataGridComboBoxColumn)gridStep.Columns[0]).SelectedValuePath = "ID";
                    //((DataGridComboBoxColumn)gridStep.Columns[0]).SelectedValueBinding = new Binding("TPlanAxleID");
                }
            }
            else
            {
                gridStep.ItemsSource = new List<DB.Model.TPlanStep>();
            }
        }
        private void bindAxleList()
        {
            int tpid = getCurrentTPID();
            if (tpid > 0)
            {
                DB.Model.TPlan tp = m_tManager.getModel(tpid);
                if (tp != null)
                {
                    txtTotalLoopTimes.Text = tp.LoopTimes.ToString();
                    m_axleList = tp.AxleList;
                }
            }
            else
            {
                m_axleList = new List<DB.Model.TPlanAxle>();
            }

            if (m_axleList == null)
            {
                m_axleList = new List<DB.Model.TPlanAxle>();
            }
        }
        void setControl(List<DB.Model.TPlanAxle> aList, string aName,KZ400B.Controls.TPlan.TPlanAxle aControl)
        {
            if (aList == null || string.IsNullOrEmpty(aName) || aControl == null) return;
            if (aList.Count(n => n.AxleName.Equals(aName)) > 0)
            {
                DB.Model.TPlanAxle ta = aList.First(n => n.AxleName.Equals(aName));
                aControl.IsEnabled = true;
                if(AxleCacheManager.AxleList.ContainsKey(aName))
                {
                    aControl.RunningUnitValue = (int)AxleCacheManager.AxleList[aName].RunningUnit;//ta.RunUnit;
                }
                else
                {
                    aControl.RunningUnitValue = 0 ;
                }
                aControl.StartPostionText = (ta.StartPosition ?? 0).ToString(MySetting.PositionDisDeciFormatter);
            }
            else
            {
                aControl.IsEnabled = false;
            }
        }
        private void setTPlanID()
        {
            int tpid = getCurrentTPID();

            List<DB.Model.TPlanAxle> aList = m_tManager.getAxleList(tpid);

            xControl.TPlanID = 0;
            yControl.TPlanID = 0;
            zControl.TPlanID = 0;
            tControl.TPlanID = 0;
            uControl.TPlanID = 0;
            wControl.TPlanID = 0;


            xControl.TPlanID = tpid;
            yControl.TPlanID = tpid;
            zControl.TPlanID = tpid;
            tControl.TPlanID = tpid;
            uControl.TPlanID = tpid;
            wControl.TPlanID = tpid;

            //if (aList != null)
            //{
            //    setControl(aList, "X", xControl);
            //    setControl(aList, "Y", yControl);
            //    setControl(aList, "Z", zControl);
            //    setControl(aList, "T", tControl);
            //    setControl(aList, "U", uControl);
            //    setControl(aList, "W", wControl);
            //}

            xControl.IsReadOnly = true;
            yControl.IsReadOnly = true;

            xControl.Visibility = xControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            yControl.Visibility = yControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            zControl.Visibility = zControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            tControl.Visibility = tControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            uControl.Visibility = uControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            wControl.Visibility = wControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;


            xPL.Visibility = xControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            yPL.Visibility = yControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            zPL.Visibility = zControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            tPL.Visibility = tControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            uPL.Visibility = uControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;
            wPL.Visibility = wControl.IsEnabled && tpid > 0 ? Visibility.Visible : Visibility.Collapsed;

            spStatus.Visibility = tpid > 0 ? Visibility.Visible : Visibility.Collapsed;


            xControl.IsReadOnly = true;
            yControl.IsReadOnly = true;
            zControl.IsReadOnly = true;
            tControl.IsReadOnly = true;
            uControl.IsReadOnly = true;
            wControl.IsReadOnly = true;
        }
        private int m_tpId = 0;
        //private int m_tmpTpId = 0;
        private void cmbPlan_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int tpid = getCurrentTPID();
            if (m_tpId != tpid)
            {
                m_tManager.Stop(m_tpId);
                if (m_tpId > 0)
                {
                    TPRStateManager.Instance.Update(m_tpId);
                }
            }
            
            
            
            
            bindPlans(tpid,false,true);
            System.Windows.Visibility hid = System.Windows.Visibility.Hidden;
            System.Windows.Visibility colp = System.Windows.Visibility.Collapsed;
            System.Windows.Visibility vis = System.Windows.Visibility.Visible;
            if (tpid == 0)
            {
                gridStep.Visibility = hid;
                spTotalLoops.Visibility = hid;
                btnSavePlan.Visibility = colp;
                btnEditPlan.Visibility = colp;
                btnRmPlan.Visibility = colp;
                spStatus.Visibility = hid;
            }
            else
            {
                gridStep.Visibility = vis;
                spTotalLoops.Visibility = vis;
                btnSavePlan.Visibility = vis;
                btnEditPlan.Visibility = vis;
                btnRmPlan.Visibility = vis;
                spStatus.Visibility = vis;

                m_tpId = tpid;
            }
            
        }

        private void btnAddPlan_Click(object sender, RoutedEventArgs e)
        {
            TPlanAdd tpAdd = new TPlanAdd();
            tpAdd.ShowDialog();
            
            bindPlans(tpAdd.TPlanID,true);
        }

        int getCurrentTPID()
        {
            int tpid = 0;
            if (cmbPlan.SelectedValue != null)
            {
                if (!int.TryParse(cmbPlan.SelectedValue.ToString(), out tpid))
                {
                    tpid = 0;
                }
            }
            else if (cmbPlan.SelectionBoxItem != null && cmbPlan.SelectionBoxItem is DB.Model.TPlan)
            {
                DB.Model.TPlan ntp = cmbPlan.SelectionBoxItem as DB.Model.TPlan;
                tpid = ntp != null ? ntp.ID : 0;
            }
            else if (cmbPlan.SelectedItem != null && cmbPlan.SelectedItem is DB.Model.TPlan)
            {
                DB.Model.TPlan ntp = cmbPlan.SelectedItem as DB.Model.TPlan;
                tpid = ntp != null ? ntp.ID : 0;
            }
            return tpid;
            ////int tpid = 0;
            ////if (cmbPlan.SelectedValue != null)
            ////{
            ////    if (!int.TryParse(cmbPlan.SelectedValue.ToString(), out tpid))
            ////    {
            ////        tpid = 0;
            ////    }
            ////}
            ////return tpid;
            //return m_tpId;
        }

        private void btnBackPlan_Click(object sender, RoutedEventArgs e)
        {
            m_tManager.Stop(getCurrentTPID());
            this.Close();
        }

        private void btnRmPlan_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                m_tManager.delete(getCurrentTPID());
                bindPlans(0);
                MessageBox.Show(string.Format("删除成功"));
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("删除失败:{0}",ex.Message));
            }
        }

        private void btnEditPlan_Click(object sender, RoutedEventArgs e)
        {
            int tpid = getCurrentTPID();
            if (tpid <= 0)
            {
                MessageBox.Show("请选择一个方案");
                return;
            }
            TPlanEdit tpAdd = new TPlanEdit(tpid);
            tpAdd.ShowDialog();

            bindPlans(getCurrentTPID(),true);
        }

        private void btnSavePlan_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int tpid = getCurrentTPID();
                List<DB.Model.TPlanStep> stepList = gridStep.ItemsSource as List<DB.Model.TPlanStep>;
                foreach (DB.Model.TPlanStep step in stepList)
                {
                    if (step == null)
                    {
                        continue;
                    }
                    step.TPlanID = tpid;
                    if (step.ID > 0)
                    {
                        m_tManager.updateStep(step);
                    }
                    else
                    {
                        m_tManager.addStep(step);
                    }
                }
                bindSteps();
                MessageBox.Show(string.Format("保存成功"));
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("保存失败:{0}",ex.Message));
            }

        }

        private void btnDelTPlanAxleID_Click(object sender, RoutedEventArgs e)
        {
            
            if (gridStep.SelectedIndex != 0)
            {
                int index = gridStep.SelectedIndex;
                List<DB.Model.TPlanStep> stepList = gridStep.ItemsSource as List<DB.Model.TPlanStep>;
                if (stepList != null && stepList.Count > 0)
                {
                    if (index < stepList.Count)
                    { 
                        DB.Model.TPlanStep st = stepList[index];
                        if (st != null)
                        {
                            m_tManager.removeStep(st);
                        }
                    }
                }
            }
            
            bindSteps();
        }

        

        private void gridStep_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            if (_defaultRowControlTemplate == null)
            {
                _defaultRowControlTemplate = e.Row.Template;
            }
            if (e.Row.Item == CollectionView.NewItemPlaceholder)
            {
                e.Row.Template = _newRowControlTemplate;
                e.Row.UpdateLayout();
            }
        }

        private void gridStep_UnloadingRow(object sender, DataGridRowEventArgs e)
        {
            if (e.Row.Item == CollectionView.NewItemPlaceholder && e.Row.Template != _defaultRowControlTemplate)
            {
                try
                {
                    e.Row.Template = _defaultRowControlTemplate;
                    e.Row.UpdateLayout();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }



        private void gridStep_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
        {
            IEditableCollectionView iecv = CollectionViewSource.GetDefaultView((sender as DataGrid).ItemsSource) as IEditableCollectionView;
            if (iecv.IsAddingNew)
            {
                // need to wait till after the operation as the NewItemPlaceHolder is added after
                Dispatcher.Invoke(new DispatcherOperationCallback(ResetNewItemTemplate)
                    , DispatcherPriority.ApplicationIdle
                    , gridStep);
            }
        }

        public DataGridRow GetRow(DataGrid dataGrid, int index)
        {
            DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
            if (row == null)
            {
                dataGrid.ScrollIntoView(dataGrid.Items[index]);
                dataGrid.UpdateLayout();

                row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
            }

            return row;
        }

        private object ResetNewItemTemplate(object arg)
        {
            DataGridRow row = GetRow(gridStep, gridStep.Items.Count - 1);
            if (row.Template != _newRowControlTemplate)
            {
                row.Template = _newRowControlTemplate;
                row.UpdateLayout();
            }
            labStepTip.Visibility = System.Windows.Visibility.Collapsed;
            return null;
        }


        private void MyGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DataGridRow row = sender as DataGridRow;
            if (row.Item == CollectionView.NewItemPlaceholder && row.Template == _newRowControlTemplate)
            {
                row.Template = _defaultRowControlTemplate;
                row.UpdateLayout();
                this.gridStep.CurrentItem = row.Item;
                DataGridCell cell = GetCell(gridStep, gridStep.Items.IndexOf(row.Item), 0);
                cell.Focus();
                this.gridStep.BeginEdit();
            }
            labStepTip.Visibility = System.Windows.Visibility.Visible;
        }


        public DataGridCell GetCell(DataGrid dataGrid, int row, int column)
        {
            DataGridRow rowContainer = GetRow(dataGrid, row);
            if (rowContainer != null)
            {
                DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);


                DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
                if (cell == null)
                {

                    dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[column]);

                    cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
                }

                return cell;
            }

            return null;
        }

        public T GetVisualChild<T>(Visual parent) where T : Visual
        {
            T child = default(T);

            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++)
            {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                child = v as T;
                if (child == null)
                {
                    child = GetVisualChild<T>(v);
                }
                if (child != null)
                {
                    break;
                }
            }

            return child;
        }

    }
}
